#############################################################
### Code to create Figures 7 and 8, Appendix Tables 12-13 ###
#############################################################



################################################################################
### Setup 
###
### The donor analysis requires the merging of three sources:
### tweets, member information, and donor information.

# Clear workspace, Load packages
rm(list=ls())
library(ggplot2)
library(dplyr)
library(lubridate)
library(stargazer)
library(sjPlot)
library(jtools)
library(lfe)
library(data.table)



### Import, clean, and merge member and donor information

# Load FEC data by cycle
donors10 <- read.csv("contributions_2009_2010.csv")
donors12 <- read.csv("contributions_2011_2012.csv")
donors14 <- read.csv("contributions_2013_2014.csv")
donors16 <- read.csv("contributions_2015_2016.csv")
donors18 <- read.csv("contributions_2017_2018.csv")
donors20 <- read.csv("contributions_2019_2020.csv")

# Rename FEC committee variable
donors10 <- rename(donors10, FECcommittee = X)
donors12 <- rename(donors12, FECcommittee = X)
donors14 <- rename(donors14, FECcommittee = X)
donors16 <- rename(donors16, FECcommittee = X)
donors18 <- rename(donors18, FECcommittee = X)
donors20 <- rename(donors20, FECcommittee = X)

# Import member files by Congress
c111 <- read.csv("Members by Congress 111th.csv")
c112 <- read.csv("Members by Congress 112th.csv")
c113 <- read.csv("Members by Congress 113th.csv")
c114 <- read.csv("Members by Congress 114th.csv")
c115 <- read.csv("Members by Congress 115th.csv")
c116 <- read.csv("Members by Congress 116th.csv")

# Merge donor files and member information
donors10 <- merge(donors10, c111, by = "FECcommittee")
donors12 <- merge(donors12, c112, by = "FECcommittee")
donors14 <- merge(donors14, c113, by = "FECcommittee")
donors16 <- merge(donors16, c114, by = "FECcommittee")
donors18 <- merge(donors18, c115, by = "FECcommittee")
donors20 <- merge(donors20, c116, by = "FECcommittee")

# Combine to single file
donors <- rbind(donors10, donors12, donors14, donors16, donors18, donors20)

# Create date variables
donors$date <- ymd(donors$X.1)
donors$year <- year(donors$date)
donors$week <- lubridate::week(donors$date)
donors$month <- lubridate::month(donors$date)

# Create yearmonth and yearweek variables
donors$yearmonth <- paste0(as.character(donors$year),"Y", as.character(donors$month))
donors$yearweek <- paste0(as.character(donors$year),"Y", as.character(donors$week))

# Group donations by month and week
donationsmonth <- donors %>%
  group_by(icpsr, yearmonth) %>% 
  dplyr::summarize(
    monthamount = sum(amount),
    monthdonors = sum(donors)
  ) %>% 
  ungroup()
donationsweek <- donors %>%
  group_by(icpsr, yearweek) %>% 
  dplyr::summarize(
    weekamount = sum(amount),
    weekdonors = sum(donors)
  ) %>% 
  ungroup()


### Load and clean tweets, merge with member-donor data

# Load tweets
tweets <- fread("activetweets111-116.csv")

# Load handles, subset to relevant columns
handles <- read.csv("US Congress Handles Master List.csv")
handles <- dplyr::select(handles, icpsr, twitter_lower)

# Join tweets with handles (adds party info to tweets)
tweets <- right_join(tweets, handles, by = "twitter_lower")

# Add dates columns to tweets
tweets$year <- year(tweets$created_at)
tweets$week <- lubridate::week(tweets$created_at)
tweets$month <- lubridate::month(tweets$created_at)

# Create yearmonth and yearweek variables
tweets$yearmonth <- paste0(as.character(tweets$year),"Y", as.character(tweets$month))
tweets$yearweek <- paste0(as.character(tweets$year),"Y", as.character(tweets$week))

# Remove NAs for dates
tweets <- filter(tweets, !is.na(week))

# Group tweets by month and week for each member
tweetsmonth <- tweets %>%
  group_by(icpsr, yearmonth) %>% 
  dplyr::summarize(
    tweets = n(),
    polarizing = sum(polarizing)
  ) %>% 
  ungroup()
tweetsweek <- tweets %>%
  group_by(icpsr, yearweek) %>% 
  dplyr::summarize(
    tweets = n(),
    polarizing = sum(polarizing)
  ) %>% 
  ungroup()

# Push NAs for polarizing to 0
tweetsmonth$polarizing[is.na(tweetsmonth$polarizing)] <- 0
tweetsweek$polarizing[is.na(tweetsweek$polarizing)] <- 0

# Create percent polarizing
tweetsmonth$pct.polarizing <- (tweetsmonth$polarizing/tweetsmonth$tweets) * 100
tweetsweek$pct.polarizing <- (tweetsweek$polarizing/tweetsweek$tweets) * 100

# Create member-date identifiers in both tweets and donations data
tweetsmonth$icpsryearmonth <- paste0(as.character(tweetsmonth$icpsr),"M", 
                                     as.character(tweetsmonth$yearmonth))
tweetsweek$icpsryearweek <- paste0(as.character(tweetsweek$icpsr),"M", 
                                   as.character(tweetsweek$yearweek))
donationsmonth$icpsryearmonth <- paste0(as.character(donationsmonth$icpsr),"M", 
                                        as.character(donationsmonth$yearmonth))
donationsweek$icpsryearweek <- paste0(as.character(donationsweek$icpsr),"M", 
                                      as.character(donationsweek$yearweek))

# Remove extra variables from tweetsmonth and tweetsweek
tweetsmonth <- tweetsmonth %>%
  dplyr::select(-c(icpsr, yearmonth))
tweetsweek <- tweetsweek %>%
  dplyr::select(-c(icpsr, yearweek))

# Merge tweets and donor data
dandtmonth <- left_join(donationsmonth, tweetsmonth, by = "icpsryearmonth")
dandtweek <- left_join(donationsweek, tweetsweek, by = "icpsryearweek")

# If any remaining NAs for number of (polarizing) tweets, push to 0s
dandtmonth$tweets[is.na(dandtmonth$tweets)] <- 0
dandtmonth$polarizing[is.na(dandtmonth$polarizing)] <- 0
dandtweek$tweets[is.na(dandtweek$tweets)] <- 0
dandtweek$polarizing[is.na(dandtweek$polarizing)] <- 0

# Create pct.polarizing*polarizing (polarizing^2/tweets)
dandtmonth <- mutate(dandtmonth,
                     polarizing_sq = (polarizing * polarizing) / tweets)
dandtweek <- mutate(dandtweek,
                     polarizing_sq = (polarizing * polarizing) / tweets)



################################################################################
### Running models

# Models predicting amount donated monthly
monthamountpp <- felm(monthamount ~ pct.polarizing | icpsr + yearmonth, data=dandtmonth)
monthamountcount <- felm(monthamount ~ polarizing  | icpsr + yearmonth, data=dandtmonth)
monthamounttweets <- felm(monthamount ~ tweets | icpsr + yearmonth, data=dandtmonth)
monthamountsq <- felm(monthamount ~ polarizing_sq | icpsr + yearmonth, data=dandtmonth)

# Models predicting number of donors monthly
monthdonorspp <- felm(monthdonors ~ pct.polarizing | icpsr + yearmonth, data=dandtmonth)
monthdonorscount <- felm(monthdonors ~ polarizing  | icpsr + yearmonth, data=dandtmonth)
monthdonorstweets <- felm(monthdonors ~ tweets | icpsr + yearmonth, data=dandtmonth)
monthdonorssq <- felm(monthdonors ~ polarizing_sq | icpsr + yearmonth, data=dandtmonth)

## Appendix Table 10 (Monthly models)
stargazer(monthamountpp, monthamountcount, monthamounttweets, monthamountsq, 
          monthdonorspp, monthdonorscount, monthdonorstweets, monthdonorssq,
          type='latex',
          Title = "Monthly Member Twitter Activity and Fundraising Trends", 
          covariate.labels = c("Pct. Polarizing", "Polarizing Tweets", 
                               "Total Tweets", "Polarizing�Pct.Polarizing"),
          dep.var.labels  = c("Amount Donated", "Number of Donors")
          )

# Models predicting amount donated weekly
weekamountpp <- felm(weekamount ~ pct.polarizing | icpsr + yearweek, data=dandtweek)
weekamountcount <- felm(weekamount ~ polarizing  | icpsr + yearweek, data=dandtweek)
weekamounttweets <- felm(weekamount ~ tweets | icpsr + yearweek, data=dandtweek)
weekamountsq <- felm(weekamount ~ polarizing_sq | icpsr + yearweek, data=dandtweek)

# Models predicting number of donors weekly
weekdonorspp <- felm(weekdonors ~ pct.polarizing | icpsr + yearweek, data=dandtweek)
weekdonorscount <- felm(weekdonors ~ polarizing  | icpsr + yearweek, data=dandtweek)
weekdonorstweets <- felm(weekdonors ~ tweets | icpsr + yearweek, data=dandtweek)
weekdonorssq <- felm(weekdonors ~ polarizing_sq | icpsr + yearweek, data=dandtweek)

## Appendix Table 11 (Weekly models)
stargazer(weekamountpp, weekamountcount, weekamounttweets, weekamountsq, 
          weekdonorspp, weekdonorscount, weekdonorstweets, weekdonorssq,
          Title = "Weekly Member Twitter Activity and Fundraising Trends", 
          type="latex",  
          covariate.labels = c("Pct. Polarizing", "Polarizing Tweets", 
                               "Total Tweets", "Polarizing�Pct.Polarizing"),
          dep.var.labels  = c("Amount Donated", "Number of Donors")
          )



################################################################################
### Plotting effects

# Put models into lists so we can get coefs and SEs more easily
weekamount <- list(weekamountcount, weekamounttweets, 
                   weekamountpp, weekamountsq)
weekdonors <- list(weekdonorscount, weekdonorstweets, 
                   weekdonorspp, weekdonorssq)
monthamount <- list(monthamountcount, monthamounttweets, 
                    monthamountpp, monthamountsq)
monthdonors <- list(monthdonorscount, monthdonorstweets, 
                    monthdonorspp, monthdonorssq)

# Function to extract coefs and CIs in a plot-friendly format
effPlotDat <- function(model){
  # Pull coefficient
  coefs <- summary(model)$coefficients
  coef <- coefs[,'Estimate']
  # Pull CI
  ci <- coefs[,'Std. Error']*1.96
  # Combine/return
  effs <- c(coef=coef, ci=ci)
  effs
}

# Extract coefs and CIs
effs_week <- lapply(list(weekamount, weekdonors), function(x){
  sapply(x, effPlotDat) %>% t()
})
effs_month <- lapply(list(monthamount, monthdonors), function(x){
  sapply(x, effPlotDat) %>% t()
})

# Plot monthly effects (Figure 7)
barCenters_amt <- barplot(effs_month[[1]][,'coef'], ylim=c(0, 700))
barCenters_don <- barplot(effs_month[[2]][,'coef'], ylim=c(0, 5.5))
jpeg('polarizing_monthly_effects.jpg', width=16, height=8, units='in', res=300)
par(mar=c(3.1, 4.1, 2.1, 1.1), mfrow=c(1,2))
barplot(effs_month[[1]][,'coef'], 
        ylim=c(0, 700), ylab='Monthly Fundraising Amount Increase', 
        names.arg=c('# Polarizing', '# Tweets', '
                    % Polarizing', '(# Polarizing) * \n(% Polarizing)'))
for(ii in 1:4){
  segments(x0=barCenters_amt[ii], 
           y0=effs_month[[1]][ii,'coef']-effs_month[[1]][ii,'ci'], 
           y1=effs_month[[1]][ii,'coef']+effs_month[[1]][ii,'ci'], 
           lwd=3)
  arrows(x0=barCenters_amt[ii], 
         y0=effs_month[[1]][ii,'coef']-effs_month[[1]][ii,'ci'], 
         y1=effs_month[[1]][ii,'coef']+effs_month[[1]][ii,'ci'], 
         lwd=3, angle=90, code=3, length=0.05)  
  text(x=barCenters_amt[ii], 
       y=effs_month[[1]][ii,'coef']/4, 
       paste0(round(effs_month[[1]][ii,'coef'], 2), ' +/- ', round(effs_month[[1]][ii,'ci'], 2)))
}

barplot(effs_month[[2]][,'coef'], ylim=c(0, 5.5), 
        ylab='Monthly Donors Increase', 
        names.arg=c('# Polarizing', '# Tweets', 
                    '% Polarizing', '(# Polarizing) * \n(% Polarizing)'))
for(ii in 1:4){
  segments(x0=barCenters_don[ii], 
           y0=effs_month[[2]][ii,'coef']-effs_month[[2]][ii,'ci'], 
           y1=effs_month[[2]][ii,'coef']+effs_month[[2]][ii,'ci'], 
           lwd=3)
  arrows(x0=barCenters_don[ii], 
         y0=effs_month[[2]][ii,'coef']-effs_month[[2]][ii,'ci'], 
         y1=effs_month[[2]][ii,'coef']+effs_month[[2]][ii,'ci'], 
         lwd=3, angle=90, code=3, length=0.05)  
  text(x=barCenters_don[ii], 
       y=effs_month[[2]][ii,'coef']/4, 
       paste0(round(effs_month[[2]][ii,'coef'], 2), ' +/- ', round(effs_month[[2]][ii,'ci'], 2)))
}
par(mar=c(5.1, 4.1, 4.1, 2.1), mfrow=c(1,1))
dev.off()

# Plot weekly effects (Figure 8)
barCenters_amt <- barplot(effs_week[[1]][,'coef'], ylim=c(0, 400))
barCenters_don <- barplot(effs_week[[2]][,'coef'], ylim=c(0, 3.5))
jpeg('polarizing_weekly_effects.jpg', width=16, height=8, units='in', res=300)
par(mar=c(3.1, 4.1, 2.1, 1.1), mfrow=c(1,2))
barplot(effs_week[[1]][,'coef'], ylim=c(0, 400), 
        ylab='Weekly Fundraising Amount Increase', 
        names.arg=c('# Polarizing', '# Tweets', '% Polarizing', 
                    '(# Polarizing) * \n(% Polarizing)')
        )
for(ii in 1:4){
  segments(x0=barCenters_amt[ii], 
           y0=effs_week[[1]][ii,'coef']-effs_week[[1]][ii,'ci'], 
           y1=effs_week[[1]][ii,'coef']+effs_week[[1]][ii,'ci'], 
           lwd=3)
  arrows(x0=barCenters_amt[ii], 
         y0=effs_week[[1]][ii,'coef']-effs_week[[1]][ii,'ci'], 
         y1=effs_week[[1]][ii,'coef']+effs_week[[1]][ii,'ci'], 
         lwd=3, angle=90, code=3, length=0.05)  
  text(x=barCenters_amt[ii], 
       y=effs_week[[1]][ii,'coef']/4, 
       paste0(round(effs_week[[1]][ii,'coef'], 2), ' +/- ', round(effs_week[[1]][ii,'ci'], 2)))
}

barplot(effs_week[[2]][,'coef'], ylim=c(0, 3.5), 
        ylab='Weekly Donors Increase', 
        names.arg=c('# Polarizing', '# Tweets', '% Polarizing', 
                    '(# Polarizing) * \n(% Polarizing)')
        )
for(ii in 1:4){
  segments(x0=barCenters_don[ii], 
           y0=effs_week[[2]][ii,'coef']-effs_week[[2]][ii,'ci'], 
           y1=effs_week[[2]][ii,'coef']+effs_week[[2]][ii,'ci'], 
           lwd=3)
  arrows(x0=barCenters_don[ii], 
         y0=effs_week[[2]][ii,'coef']-effs_week[[2]][ii,'ci'], 
         y1=effs_week[[2]][ii,'coef']+effs_week[[2]][ii,'ci'], 
         lwd=3, angle=90, code=3, length=0.05)  
  text(x=barCenters_don[ii], 
       y=effs_week[[2]][ii,'coef']/4, 
       paste0(round(effs_week[[2]][ii,'coef'], 2), ' +/- ', round(effs_week[[2]][ii,'ci'], 2)))
}
par(mar=c(5.1, 4.1, 4.1, 2.1), mfrow=c(1,1))
dev.off()
